-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
api for post upload #888
base: main
Are you sure you want to change the base?
api for post upload #888
Conversation
a4aa599
to
d7df699
Compare
7e86c43
to
c1424fe
Compare
…ot just tokens otherwise, we'd have to generate a token for our frontend
bd9e35e
to
d6e3dc4
Compare
d6e3dc4
to
e9bbc04
Compare
qs = super(FoiMessageAdmin, self).get_queryset(request) | ||
qs = qs.prefetch_related("deliverystatus") | ||
return qs | ||
return self.model.objects.with_drafts(False).prefetch_related("deliverystatus") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The super().get_queryset(request)
should be kept and extended with the filter, right? There's more happening in Django ModelAdmin's get_queryset
, like ordering. .width_drafts(False)
is fancy but only works on the manager and not the queryset which makes it difficult to compose.
@admin.register(FoiMessageDraft) | ||
class FoiMessageDraftAdmin(FoiMessageAdmin): | ||
def get_queryset(self, request): | ||
return self.model.objects.all().prefetch_related("deliverystatus") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should also call super
and possibly just show drafts?
from ..auth import can_write_foirequest | ||
|
||
|
||
class OwnsFoiRequestPermission(permissions.BasePermission): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rename to WriteFoiRequestPermission
? The concept of owning
is not clearly defined in the code base apart from request.user == object.user
which is not what is checked here.
if request.method in permissions.SAFE_METHODS: | ||
return True | ||
|
||
return can_write_foirequest(getattr(obj, self.request_field), request) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this can work with belongs_to__request
used in the FoiAttachmentViewSet
as this is just attribute access.
# the other kinds can only be created by the system | ||
MESSAGE_KIND_USER_ALLOWED = [ | ||
MessageKind.POST, | ||
MessageKind.PHONE, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are not using PHONE
or VISIT
. Should we disallow their creation? Otherwise we might get random visit messages in the database.
raise serializers.ValidationError("Only draft messages can be altered.") | ||
|
||
def create(self, validated_data): | ||
return super().create(validated_data) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should create a FoiEvent
for auditing purposes when the message is created and/or finalized, either directly or by sending a signal. (example)
def get_queryset(self): | ||
return super().get_queryset().filter(is_draft=False) | ||
return self.with_drafts() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not calling super
here is just a workaround because the method is only defined on the manager and doesn't exist on the queryset. Looks great as an API, but the problem I see here: we are using inheritance but then not calling super
. A subtle bug may arise if FoiMessageManager
get its own get_queryset
method which is then not called.
Alternatives:
- define a custom queryset instead which has the
with_drafts
method. You can create a matching manager by usingobjects = FoiMessageQueryset.as_manager()
. - Define a function
with_drafts(qs: Queryset) -> Queryset
andreturn with_drafts(super().get_queryset())
@@ -201,6 +212,9 @@ def save(self, *args, **kwargs): | |||
|
|||
super().save(*args, **kwargs) | |||
|
|||
def is_public(self) -> bool: | |||
return self.is_draft is False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This works and is likely going to continue to work but it makes me uneasy as the intention here does not match the operator: comparing identity instead of checking truthiness. If you don't care about identity, don't compare it. It can be a subtle source of bugs because it can be an implementation detail. Favorite example:
>>> x = 3
>>> y = 3
>>> x is y
True
>>> x = 123123123123123
>>> y = 123123123123123
>>> x == y
True
>>> x is y
False
What we want is return not self.is_draft
.
requests = [int(r) for r in requests] | ||
except ValueError: | ||
except (ValueError, AttributeError): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably check self.request is None
explicitly and return a value. Otherwise we might hide request.query_params
no longer being an attribute or any other AttributeError
s. Keeping try/except small and focused is a good idea.
try: | ||
if self.request.user.is_superuser: | ||
return GeoRegionDetailSerializer | ||
return self.serializer_action_classes[self.action] | ||
except (KeyError, AttributeError): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, should handle self.request is None
explicitly and bail with a value.
notable changes:
foirequest/api_views.py
into multiple files. this is a breaking change i.e. for froide-campaign and froide-food. checkout their respective branches for testing:CreateOnlyWithScopePermission
, so that regular authentication can also be used. please review carefully, see df7b5a3ts client example: